#include <string.h>
#include <jni.h>
#include <android/log.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
const char HexCode[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
const char *sha1final="3D0556B10DE1400C82FFA3721CED4AD9";
const char *md52final="DCA5375C5EA97D8877ED938CA086E4E7";
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "shuai", __VA_ARGS__)
jobject getApplication(JNIEnv *env) {
	jclass localClass = (*env)->FindClass(env,"android/app/ActivityThread");
	if (localClass!=NULL)
	{
		// LOGI("class have find");
		jmethodID getapplication = (*env)->GetStaticMethodID(env,localClass, "currentApplication", "()Landroid/app/Application;");
		if (getapplication!=NULL)
		{
			jobject application = (*env)->CallStaticObjectMethod(env,localClass, getapplication);
			return application;
		}
		return NULL;
	}
	return NULL;
}
void exitApplication(JNIEnv *env, jint flag){
	jclass temp_clazz = NULL;
	jmethodID mid_static_method;
	// 1、从classpath路径下搜索ClassMethod这个类，并返回该类的Class对象
	temp_clazz =(*env)->FindClass(env,"java/lang/System");
	mid_static_method = (*env)->GetStaticMethodID(env,temp_clazz,"exit","(I)V");
	(*env)->CallStaticVoidMethod(env,temp_clazz,mid_static_method,flag);
	(*env)->DeleteLocalRef(env,temp_clazz);
}
void verficSing(JNIEnv* env, jobject thiz){
	jobject context= getApplication(env);
	jclass  activity = (*env)->GetObjectClass(env,context);
	// 得到 getPackageManager 方法的 ID
	jmethodID methodID_func = (*env)->GetMethodID(env,activity, "getPackageManager", "()Landroid/content/pm/PackageManager;");
	// 获得PackageManager对象
	jobject packageManager = (*env)->CallObjectMethod(env,context,methodID_func);
	jclass packageManagerclass = (*env)->GetObjectClass(env,packageManager);
	//得到 getPackageName 方法的 ID
	jmethodID methodID_pack = (*env)->GetMethodID(env,activity,"getPackageName", "()Ljava/lang/String;");
	//获取包名
	jstring name_str = (jstring)((*env)->CallObjectMethod(env,context, methodID_pack));
	// 得到 getPackageInfo 方法的 ID
	jmethodID methodID_pm = (*env)->GetMethodID(env,packageManagerclass,"getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
	// 获得应用包的信息
	jobject package_info = (*env)->CallObjectMethod(env,packageManager, methodID_pm, name_str, 64);
	// 获得 PackageInfo 类
	jclass package_infoclass = (*env)->GetObjectClass(env,package_info);
	// 获得签名数组属性的 ID
	jfieldID fieldID_signatures = (*env)->GetFieldID(env,package_infoclass,"signatures", "[Landroid/content/pm/Signature;");
	// 得到签名数组，待修改
	jobject signatur = (*env)->GetObjectField(env,package_info, fieldID_signatures);
	jobjectArray  signatures = (jobjectArray)(signatur);
	// 得到签名
	jobject signature = (*env)->GetObjectArrayElement(env,signatures, 0);
	// 获得 Signature 类，待修改
	jclass signature_clazz = (*env)->GetObjectClass(env,signature);
	//--------old---------------
	//获取sign
	jmethodID toCharString = (*env)->GetMethodID(env,signature_clazz, "toCharsString", "()Ljava/lang/String;");
	//获取签名字符；或者其他进行验证操作
	jstring signstr = (jstring)((*env)->CallObjectMethod(env,signature, toCharString));
	//--------old_end----------------------
	//--------------new--------------
	//Signature.toByteArray()
	jmethodID tobyte_methodId = (*env)->GetMethodID(env,signature_clazz, "toByteArray", "()[B");
	jbyteArray signature_byte = (jbyteArray) (*env)->CallObjectMethod(env,signature, tobyte_methodId);
	//new ByteArrayInputStream
	jclass byte_array_input_class=(*env)->FindClass(env,"java/io/ByteArrayInputStream");
	jmethodID init_methodId=(*env)->GetMethodID(env,byte_array_input_class,"<init>","([B)V");
	jobject byte_array_input=(*env)->NewObject(env,byte_array_input_class,init_methodId,signature_byte);
	//CertificateFactory.getInstance("X.509")
	jclass certificate_factory_class=(*env)->FindClass(env,"java/security/cert/CertificateFactory");
	jmethodID certificate_methodId=(*env)->GetStaticMethodID(env,certificate_factory_class,"getInstance","(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;");
	jstring x_509_jstring=(*env)->NewStringUTF(env,"X.509");
	jobject cert_factory=(*env)->CallStaticObjectMethod(env,certificate_factory_class,certificate_methodId,x_509_jstring);
	//certFactory.generateCertificate(byteIn);
	jmethodID certificate_factory_methodId=(*env)->GetMethodID(env,certificate_factory_class,"generateCertificate",("(Ljava/io/InputStream;)Ljava/security/cert/Certificate;"));
	jobject x509_cert=(*env)->CallObjectMethod(env,cert_factory,certificate_factory_methodId,byte_array_input);

	//cert.getEncoded()
	jclass x509_cert_class=(*env)->GetObjectClass(env,x509_cert);
	jmethodID x509_cert_methodId=(*env)->GetMethodID(env,x509_cert_class,"getEncoded","()[B");
	jbyteArray cert_byte=(jbyteArray)(*env)->CallObjectMethod(env,x509_cert,x509_cert_methodId);

	//MessageDigest.getInstance("SHA1")
	jclass message_digest_class=(*env)->FindClass(env,"java/security/MessageDigest");
	jmethodID methodId=(*env)->GetStaticMethodID(env,message_digest_class,"getInstance","(Ljava/lang/String;)Ljava/security/MessageDigest;");
	//jstring sha1_jstring=(*env)->NewStringUTF(env,"SHA1");
	jstring sha1_jstring=(*env)->NewStringUTF(env,"MD5");
	jobject sha1_digest=(*env)->CallStaticObjectMethod(env,message_digest_class,methodId,sha1_jstring);

	//sha1.digest (certByte)
	methodId=(*env)->GetMethodID(env,message_digest_class,"digest","([B)[B");
	jbyteArray sha1_byte=(jbyteArray)(*env)->CallObjectMethod(env,sha1_digest,methodId,cert_byte);
	//toHexString
	jsize array_size=(*env)->GetArrayLength(env,sha1_byte);
	jbyte* sha1 =(*env)->GetByteArrayElements(env,sha1_byte,NULL);
	//char *hex_sha=char[array_size*2+1];
	char hex_sha[array_size*2+1];
	int i;
	for (i = 0;i<array_size;++i) {
		hex_sha[2*i]=HexCode[((unsigned char)sha1[i])/16];
		hex_sha[2*i+1]=HexCode[((unsigned char)sha1[i])%16];
	}
	hex_sha[array_size*2]='\0';
	//LOGV("sin-sha1:%s",hex_sha);
	//--------------------------------
	const  char *sign=(*env)->GetStringUTFChars(env,signstr,NULL);
	int flag=0;
	if (strcmp(hex_sha,sha1final)!=0){
		LOGV("Verification fail");
		flag=-1;
		if(strcmp(hex_sha,md52final)!=0){
			flag=-1;
		}else{
			flag=0;
		}
		if(flag==-1){
			exitApplication(env,0);
		}
	}else{
		LOGV("Verification success！");
	}
}

jobjectArray
Java_com_handpay_zztong_hp_config_ZZTConfig_stringsFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
	  jstring str;
	  jsize len = 21;
	  jobjectArray args = 0;
	  verficSing(env,thiz);
	  char* sa[] = {

					  "https://safeapp.hpay.sandpay.com.cn/hpaySft/",
					  "HXZZT",
					  "3.7",
					  "9411bb0a7ad5cf33dbd9ba51a5feedabca6e9874042bac5b2273173c6f2e914e97df6b2c19f91abe2ef767c8ca3204caa29831e9c7c2dc0a0f35c31c9cce37fe8d3fb2ac9c4296e14104b27cef1a47db218bb213b880617f8e449d0f0310dc89627e695114fb197184afa415903be9e92a3b39b553ae078dc42946c81ab06105",
					  "10001",
					  "https://www.handmart.cn/web/newzzt/2.0/ServiceAgreements.html",
					  "https://www.handmart.cn/web/newzzt/2.0/Useinfo.html",
					  "https://www.handmart.cn/web/newzzt/2.0/TranserInfo.html",
					  "https://www.handmart.cn/web/newzzt/2.0/kuaisuzz.html",
					  "https://www.handmart.cn/web/newzzt/2.0/tmzz.html",
					  "http://202.101.25.178:8080/Gateway/MobilePayment",
					  "http://202.96.255.146:8080/Gateway/MobilePayment",
					  "VI01",
					  "VI02",
					  "10.48.192.19",
//					   "mpay.handpay.cn",
					  "safeapp.hpay.sandpay.com.cn",//https 请求
					  "1",
					  "HXZZT",
					  "http://mobklf.99wuxian.com",
					  "http://klfqb.99play.cn/basic/game99Qb/pages/iphone/qb_index.html",
					  "http://klfgame.99play.cn/basic/gamecardapp/pages/iphone/game99.recharge.html"};

	  int i=0;
	  args = (*env)->NewObjectArray(env,len,(*env)->FindClass(env,"java/lang/String"),0);
	  for( i=0; i < len; i++ )
	  {
	  str = (*env)->NewStringUTF(env,sa[i] );
	  (*env)->SetObjectArrayElement(env,args, i, str);
	  }
	  return args;
}
/*
static JNINativeMethod gMethods[] = {
    {"stringsFromJNI",   "()[Ljava/lang/String;", (void *)Java_com_handpay_zztong_hp_config_ZZTConfig_stringsFromJNI}
	};
static int register_methods(JNIEnv *env){
	int methodsLenght = sizeof(gMethods) / sizeof(gMethods[0]);
	return (*env)->RegisterNatives(env,"com/handpay/zztong/hp/config/ZZTConfig", gMethods, methodsLenght);
} 
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
  JNIEnv* env = NULL; 
  jint result = -1; 
  if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) 
  {
	LOGV("GetEnv error!");
    return -1; 
  }
  //assert(env != NULL); 
  if (register_methods(env) < 0) 
  {
    LOGV("register_methods error!");
    //注册
    return -1; 
  } 
  result = JNI_VERSION_1_4; 
  return result;
}*/


